home *** CD-ROM | disk | FTP | other *** search
- NAME ccyibm
- ; File CCYIBM.ASM
- ; Edit History:
- ; Mar.21,1991:
- ; * Add MASM Option /DCGA in serval places. The goal is to make ZUnet-PBX
- ; can be run in different CCDOS versions(Such as: CCDOS213,LIANXIAN,
- ; STCDOS,CGA17,etc.) on different video adapers( such as CGA,EGA,VGA
- ; and MDA).
- ; In this program Macro Conditions "IFDEF CGA ... ENDIF" and "IFNDEF CGA
- ; ... ENDIF" are used.
- ; Option CGA is used only when you want to build a program used in PC/XT
- ; (CGA or MDA adapter).Maybe it can be used in VGA adapter. [zqf]
- ; 1990:
- ; * Program is modified in many places to suit for different CCDOS versions.
- ; You can check them by indexing 'zqf' or 'CCDOS'. [zqf]
-
- ;CHINESE
- ifdef MSDOS
- include msyibm.dat
- else
- include ccyibm.dat
- endif
-
- code segment public 'code'
- extrn beep:near, prtchr:near, outchr:near, sbrk:near, pcwait:near
- extrn isfile:near, strlen:near, strcpy:near ; in mssfil
- extrn anstty:near,ansini:near,ansrei:near ; in mszibm
- extrn anstat:near,anskbi:near,ansdsl:near ; in mszibm
- extrn ans52t:near, vsinit:near ; in mszibm
- extrn msuinit:near, keybd:near ; in msuibm
- extrn tekini:near,tekcls:near,tekemu:near,tekend:near ;in msgibm
- extrn tekrint:near
- ifdef DEBG
- ; extrn debgp:near
- endif
- assume cs:code, ds:datas, es:datas
-
- ; do initialization local to this module
- ; Dynamically allocates 4000 bytes for screen save/restore buffer plus
- ; 320 to 38400 bytes for screen scroll back buffers. Tries to leave space
- ; for Command.com before enlarging buffers. [jrd]
- lclyini proc near
- call msuinit ; initialize keyboard module msuxxx
-
- mov ax,swidth*(slen+1)*2 ; (80 char + 80 attr) * 25 lines
- call sbrk ; memory allocation routine (mssker)
- ;if we get here them we have the lines
- mov scrsav,ax ; memory segment for save screens
- ; screen roll back buffers
- mov bx,0ffffh ; ask for all of memory, to get size
- mov ah,alloc ; allocate all of memory (must fail)
- int dos ; bx has # free paragraphs
- mov ax,bx ; ax has copy of number free paragraphs
- sub ax,24000D/16 ; space for Command.com copy #2
- jbe lclyin1 ; be = not enough for it. [ebb]
- cmp ax,(swidth*slen+15)/16 ; minimum roll back space left over?
- jbe lclyin1 ; be = not even that much
- cmp ax,(swidth*slen*npages+7)/8 ; paragraphs wanted for roll back
- jbe lclyin2 ; be = enough but not more than needed
- mov ax,(swidth*slen*npages+7)/8 ; limit to our actual needs
- jmp short lclyin2 ; ask for all we really want
- lclyin1:mov ax,(4*swidth+15)/16 ; use minimum needed paragraphs
- lclyin2:mov inipara,ax ; save for later resizing of buffers
- mov cl,4 ; convert paragraphs to bytes
- shl ax,cl ; for sbrk
- call sbrk ; ask for that many bytes
- ;if we get here them we have the space
- mov bwnd.orig,ax ; memory segment, bottom window area
- mov twnd.orig,ax ; top. same place for both buffers!
-
- call scrseg ; test running in an Environment
- call scrmod ; read video state, get crt_mode
- mov ax,low_rgt ; lower right corner of screen
- mov al,crt_mode
- mov crt_norm,al ; save as normal mode
- mov savflg,ax
- mov ah,conout ; output a space to set background
- mov dl,' ' ; and foreground screen colors
- int dos
- mov ah,3 ; get current cursor position into dx
- mov bh,0
- int screen
- dec dl ; backup to the space
- mov ah,2 ; set cursor
- int screen
- mov ah,8 ; read current attributes
- xor bh,bh ; page 0
- int screen
- mov scbattr,ah ; save video attributes
- mov oldattr,ah ; and here too
- mov ax,inipara ; # paragraphs allocated by DOS
- mov cl,3 ; 2**3 = 8
- shl ax,cl ; paragraphs to words (char + attrib)
- xor dx,dx ; clear extended size
- mov ch,0
- mov cl,byte ptr low_rgt
- inc cl ; number of chars per line in buffer
- div cx ; ax = number of lines in buffer
- mov bwnd.lmax,ax ; max lines per buffer (quotient)
- mov twnd.lmax,ax ; max lines per buffer
- add cx,cx ; count char and attribute per item
- xor dx,dx ; clear extended numerator
- mul cx ; ax = effective # bytes per buffer
- dec ax ; adjust for counting from zero
- mov bwnd.bend,ax ; offset of last byte in buffer
- mov twnd.bend,ax ; offset of last byte in buffer
- mov bwnd.pp,0 ; offset of first byte in buffer
- mov twnd.pp,0 ; offset of first byte in buffer
- mov bwnd.lcnt,0 ; number of lines occupied in buffer
- mov twnd.lcnt,0 ; number of lines occupied in buffer
- call vsinit ; init terminal emulator module MSZ
- mov ega_mode,0 ; assume no EGA
- mov ax,1200H ; EGA: Bios alternate select
- mov bl,10H ; Ask for EGA info
- mov bh,0ffH ; Bad info, for testing
- mov cl,0fH ; Reserved switch settings
- int screen ; EGA, are you there?
- cmp cl,0cH ; Test reserved switch settings
- jge lclyin3 ; ge = no EGA in use
- push es
- mov ax,40h ; check Bios 40:87h for ega being
- mov es,ax ; the active display adapter
- test byte ptr es:[87h],8 ; is ega active?
- pop es
- jnz lclyin3 ; nz = no
- mov ega_mode,1 ; yes, set flag to say so
- mov crt_norm,3 ; assume color monitor is attached
- cmp bh,0 ; is color mode in effect?
- je lclyin3 ; e = yes
- mov crt_norm,7 ; else use mode 7 for mono
- lclyin3:ret
- lclyini endp
-
- scrini proc near ; init screen stuff
- call scrseg ; update screen segment tv_seg(s/o)
- call scrmod ; get screen mode, low_rgt
- mov ah,3 ; get cursor position and type
- xor bh,bh ; page 0
- int screen
- mov lincur,cx ; save cursor type (scan line #'s)
- mov ax,low_rgt ; present screen text size
- cmp ax,savflg ; vs size of saved screen
- jne scrin1 ; ne = different, initialize
- jmp scrin3 ; same, skip initialization
- ; Re-initialize screen buffers
- scrin1: mov ax,inipara ; paragraphs allotted to roll back
- mov cl,3 ; 2**3 = 8
- shl ax,cl ; paragraphs to words (char + attrib)
- xor dx,dx ; clear extended size
- mov cl,byte ptr low_rgt ; number of chars per line in buffer
- inc cl ; chars per line
- xor ch,ch ; clear high byte
- div cx ; ax = number of lines in buffer
- mov bwnd.lmax,ax ; max lines per buffer (quotient)
- mov twnd.lmax,ax ; max lines per buffer
- add cx,cx ; count char and attribute per item
- xor dx,dx ; clear extended numerator
- mul cx ; ax = effective # bytes per buffer
- dec ax ; adjust for counting from zero
- mov bwnd.bend,ax ; offset of last byte in buffer
- mov twnd.bend,ax ; offset of last byte in buffer
- mov bwnd.pp,0 ; offset of first byte in buffer
- mov twnd.pp,0 ; offset of first byte in buffer
- mov bwnd.lcnt,0 ; number of lines occupied in buffer
- mov twnd.lcnt,0 ; number of lines occupied in buffer
-
- mov ega_mode,0 ; assume no EGA
- mov ax,1200H ; EGA: Bios alternate select
- mov bl,10H ; Ask for EGA info
- mov bh,0ffH ; Bad info, for testing
- mov cl,0fH ; Reserved switch settings
- int screen ; EGA, are you there?
- cmp cl,0cH ; Test reserved switch settings
- jge scrin2 ; ge = no EGA in use
- push es
- mov ax,40h ; check Bios 40:87h for ega being
- mov es,ax ; the active display adapter
- test byte ptr es:[87h],8 ; is ega active?
- pop es
- jnz scrin2 ; nz = no
- mov ega_mode,1 ; yes, set flag to say so
- mov crt_norm,3 ; assume color monitor is attached
- cmp bh,0 ; is color mode in effect?
- je scrin2 ; e = yes
- mov crt_norm,7 ; else use mode 7 for mono
- scrin2: mov ah,oldattr ; get init time attributes
- mov curattr,ah ; and set nice screen attribute
- mov scbattr,ah
- mov cursor,0 ; cursor to upper left corner
- cmp flags.vtflg,0 ; terminal type of None?
- ja scrin3 ; a = no, emulating
- mov dh,byte ptr low_rgt+1
- inc dh ; bottom
- mov dl,0 ; left corner
- jmp short scrin5
- ; Common finish code
- scrin3: mov dx,cursor ; use old cursor, if any
- cmp flags.vtflg,0 ; emulating?
- je scrin4 ; e = no
- cmp dh,byte ptr low_rgt+1 ; past logical end of screen?
- jbe scrin4 ; be = no, keep going
- mov dh,byte ptr low_rgt+1 ; yes, just use lower right corner
- scrin4: cmp dl,byte ptr low_rgt ; maybe past right margin
- jbe scrin5 ; be = no, use the way it is
- mov dl,byte ptr low_rgt
- scrin5: mov cursor,dx ; init cursor
- mov ah,2 ; set cursor position
- xor bh,bh ; page zero
- ; ---------don't set cursor in CCDOS. Dec.12,1990 [zqf]
- IFDEF CGA ; Add Option CGA to servered screen.Mar.21,1991 [zqf]
- cmp isccdos,1 ; is in CCDOS ?
- je scrin6 ; e = yes, skip
- ENDIF
- int screen ; set cursor in case it moved
- scrin6:
- ; -----------
- test flags1,inited ; have we run yet?
- jz scrin7 ; z = no, so no saved screen yet
- call restscr ; restore screen[zqf]Dec.13,1990
- scrin7: or flags1,inited ; remember we've run already
- cmp flags.modflg,1 ; is mode line on and locally owned?
- ja scrin10 ; a = host owned, leave intact
- cmp flags.vtflg,0 ; emulating a terminal?
- jne scrin8 ; ne = yes, can have mode line
- or yflags,modoff ; for no emulation say toggled off
- cmp trmtyp,0 ; previous terminal type = none?
- jne scrin9 ; ne = no. need to clear mode line
- jmp scrin10 ; yes, let 25th line be intact
- scrin8: cmp flags.modflg,0 ; is mode line disabled?
- je scrin9 ; e = yes, clear it
- test yflags,modoff ; is mode line toggled off?
- jnz scrin9 ; nz = yes, clear the line
- call modlin ; turn on mode line
- jmp short scrin10
- scrin9: call clrmod ; ensure its off
- scrin10:cmp flags.vtflg,0 ; current terminal type = None?
- je scrin12 ; e = yes, nothing to init
- mov al,yflags ; tell emulator we are back
- cmp vtclear,0 ; screen need clearing?
- jne scrin10a ; yes, do emulator reinit now
- cmp vtinited,inited ; inited emulator yet?
- je scrin11 ; e = yes
- cmp tekflg,0 ; Tek mode still active?
- jne scrin12 ; ne = yes, no re-init here
- scrin10a:call vtinit ; init it now
- mov vtclear,0 ; say screen is clear
- jmp short scrin12
- scrin11:call ansrei ; reinit the emulator
- call ansflg ; and get its flags
- scrin12:mov al,flags.vtflg ; current terminal type
- mov trmtyp,al ; place to remember it til next time
- cmp flags.vtflg,tttek ; Tek mode?
- je scrin13 ; e = yes
- cmp tekflg,0 ; Tek mode active within DEC stuff?
- je scrin14 ; e = no
- scrin13:call tekini ; reinit to get graphics screen
- scrin14:ret
- scrini endp
-
- ; Routine to initialize VT102/52/Heath-19 terminal emulator.
-
- vtinit proc near
- mov holdscr,0 ; clear holdscreen
- cmp flags.vtflg,0 ; doing emulation?
- je vtinix ; e = no
- cmp tekflg,0 ; Tek mode active?
- jne vtini2 ; ne = yes, do it's reinit
- or vtinited,inited
- call ansflg ; update ansi flags
- mov bx,argadr ; Get address of argument block
- mov dl,[bx].flgs
- and dl,lclecho
- and yflags,not lclecho
- or yflags,dl
- mov al,yflags ; Pass the flags
- mov dl,[bx].baudb ; Baud rate code in dl
- mov dh,[bx].parity ; Parity code in bits
- mov cl,4 ; 0-3 of dh
- shl dh,cl
- or dh,07H ; Just say 7 data bits
- test flags.remflg,d8bit ; eight bit display?
- jz vtini1 ; z = no
- inc dh ; set low four bits to value 8
- vtini1: call ansini ; call startup routine in mszibm
- vtinix: clc
- ret
- vtini2: call tekrint ; reinitialize Tek emulator
- clc
- ret
- vtinit endp
-
-
- argini proc near ; read passed arguments
- mov bx,argadr ; base of argument block
- mov al,[bx].flgs ; get flags
- and al,capt+emheath+havtt+trnctl+lclecho+modoff+lnwrap
- mov yflags,al ; mask for allowable and save
- mov al,[bx].prt
- mov portno,al ; update port number
- mov al,[bx].rows
- mov crt_lins,al ; init # of rows and cols
- mov ax,[bx].captr
- mov captrtn,ax ; buffer capture routine
- mov al,[bx].escc
- mov esc_ch,al
- mov parmsk,0ffh ; parity mask, assume parity = None
- cmp [bx].parity,parnon ; is parity None?
- je argini1 ; e = yes, keep all 8 bits
- mov parmsk,07fh ; else keep lower 7 bits
- argini1:ret ; that's it
- argini endp
-
- modlin proc near ; turn on mode line
- ; ************************** Change Connect Mode Line, Oct.8,1990 [zqf].
- cmp isccdos, 0 ; if in MS-DOS or CC-DOS ?
- je modl0 ; e = in MS-DOS
- jmp cmodl0 ; in CC-DOS
- ; ***
- ; ******** in MS-DOS below
- modl0: mov al,esc_ch
- mov modbuf.m_echr,' ' ; first char is initial space
- mov modbuf.m_hlp,' ' ; goes here too
- cmp al,32 ; printable?
- jnb modl1 ; yes, keep going
- add al,40h ; made printable
- mov modbuf.m_echr,5eh ; caret, note control char
- mov modbuf.m_hlp,5eh
- modl1: mov modbuf.m_echr+1,al ; fill in character
- mov modbuf.m_hlp+1,al
- mov bx,argadr ; get argument block
- mov al,[bx].baudb ; get baud bits
- mov si,offset unkbaud ; assume unknown baud
- cmp al,baudnsiz ; too big?
- jnb modl2 ; nb = yes, use default
- mov cl,size m_baud ; each is 5 bytes long
- mul cl
- mov ah,0
- add ax,offset baudn
- mov si,ax
- modl2: mov cx,size m_baud ; length of baud space
- mov di,offset modbuf.m_baud
- push es ; save es
- push ds
- pop es ; set es to datas segment
- cld
- rep movsb ; copy in baud rate
- mov al,[bx].parity ; get parity code
- shl al,1 ; each is 4 bytes long
- shl al,1
- mov ah,0
- add ax,offset parnams ; names of parity settings
- mov si,ax
- mov cx,4 ; each is 4 long
- mov di,offset modbuf.m_par
- rep movsb
- mov si,offset remmsg ; Assume remote echoing
- test yflags,lclecho ; Is remote side echoing?
- jz modl4 ; Yes, keep going
- mov si,offset lclmsg ; Else it's local echoing.
- modl4: mov cx,3 ; size of on/off
- mov di,offset modbuf.m_echo
- rep movsb
- mov al,portno ; communications port
- cmp al,' ' ; binary (non-printable)?
- jae modl5 ; ae = no, ascii
- add al,'0' ; convert to ascii
- modl5: mov modbuf.m_prt,al ; fill in port number
- mov cx,8 ; blank out terminal id field
- mov si,offset mtty ; assume no terminal emulation
- mov di,offset modbuf.m_term ; destination
- rep movsb ; copy it in
- mov modbuf.m_prn,' ' ; assume not printing the screen
- mov modbuf.m_prn+1,' '
- mov modbuf.m_prn+2,' '
- test anspflg,prtscr ; doing a print the screen?
- jz modl5a ; z = no
- mov modbuf.m_prn,'P' ; yes. display PRN at end of line
- mov modbuf.m_prn+1,'R'
- mov modbuf.m_prn+2,'N'
- modl5a: mov cx,size modfrm ; this is size of mode line
- mov si,offset modbuf ; mode line image
- pop es
- ; ****
- jmp modwrt
- ; ******** in CC-DOS below
- cmodl0: mov al,esc_ch
- mov cmodbuf.cm_echr,' ' ; first char is initial space
- mov cmodbuf.cm_hlp,' ' ; goes here too
- cmp al,32 ; printable?
- jnb cmodl1 ; yes, keep going
- add al,40h ; made printable
- mov cmodbuf.cm_echr,5eh ; caret, note control char
- mov cmodbuf.cm_hlp,5eh
- cmodl1: mov cmodbuf.cm_echr+1,al ; fill in character
- mov cmodbuf.cm_hlp+1,al
- mov bx,argadr ; get argument block
- mov al,[bx].baudb ; get baud bits
- mov si,offset cunkbaud ; assume unknown baud
- cmp al,baudnsiz ; too big?
- jnb cmodl2 ; nb = yes, use default
- mov cl,size cm_baud ; each is 5 bytes long
- mul cl
- mov ah,0
- add ax,offset baudn
- mov si,ax
- cmodl2: mov cx,size cm_baud ; length of baud space
- mov di,offset cmodbuf.cm_baud
- push es ; save es
- push ds
- pop es ; set es to datas segment
- cld
- rep movsb ; copy in baud rate
- mov al,[bx].parity ; get parity code
- shl al,1 ; each is 4 bytes long
- shl al,1
- mov ah,0
- add ax,offset cparnams ; names of parity settings
- mov si,ax
- mov cx,4 ; each is 4 long
- mov di,offset cmodbuf.cm_par
- rep movsb
- mov si,offset cremmsg ; Assume remote echoing
- test yflags,lclecho ; Is remote side echoing?
- jz cmodl4 ; Yes, keep going
- mov si,offset clclmsg ; Else it's local echoing.
- cmodl4: mov cx,4 ; size of on/off
- mov di,offset cmodbuf.cm_echo
- rep movsb
- mov al,portno ; communications port
- cmp al,' ' ; binary (non-printable)?
- jae cmodl5 ; ae = no, ascii
- add al,'0' ; convert to ascii
- cmodl5: mov cmodbuf.cm_prt,al ; fill in port number
- mov cx,8 ; blank out terminal id field
- mov si,offset mtty ; assume no terminal emulation
- mov di,offset cmodbuf.cm_term ; destination
- rep movsb ; copy it in
- mov cmodbuf.cm_prn,' ' ; assume not printing the screen
- mov cmodbuf.cm_prn+1,' '
- mov cmodbuf.cm_prn+2,' '
- test anspflg,prtscr ; doing a print the screen?
- jz cmodl5a ; z = no
- mov cmodbuf.cm_prn,'P' ; yes. display PRN at end of line
- mov cmodbuf.cm_prn+1,'R'
- mov cmodbuf.cm_prn+2,'N'
- cmodl5a: mov cx,size cmodfrm ; this is size of mode line
- mov si,offset cmodbuf ; mode line image
- pop es
- ; ************************** Oct.8,1990 [zqf].
- ; alternate entry to write an alternate mode line
- modwrt: push cx
- push si ; save mode line and size
- mov ah,3 ; read cursor position
- xor bx,bx ; screen page 0
- int screen
- mov cursor,dx ; save cursor position
- call trmatt ; Get terminal attributes
- and ah,77h ; omit blinking/bold attributes
- mov bh,ah ; get video attribute
- mov dx,low_rgt ; right most column
- inc dh ; refer to status line
- mov ch,dh ; bottom line [dlk]
- mov cl,0 ; left col = 0 (first) [dlk]
- mov ax,600h ; scroll to clear the line
- ;**** Modify to suit CCDOS. Sept 5,1990 [zqf]
- cmp isccdos,1 ; if in CCDOS ?
- jne modl5b ; ne = No, in MS-DOS
- mov ax,cx ; in CCDOS
- mov bx,dx
- call atsclr ; clear mode line in CC-DOS
- jmp modl5c
- modl5b: int screen ; clear mode line in MS-DOS
- modl5c:
- ;****
- mov dh,byte ptr low_rgt+1 ; refer to status line
- inc dh
- xor dl,dl ; left most column
- mov bh,0
- mov ah,2 ; set cursor position
- int screen
- pop si
- pop cx ; restore these
- cmp cl,crt_cols ; mode line longer than screen?
- jbe modl6 ; le = no
- mov cl,crt_cols ; else do just one line's worth
- dec cx ; don't let screen scroll
- modl6: cld
- lodsb ; get a byte
- mov ah,14 ; write to terminal
- mov bh,0 ; page 0
- int screen
- loop modl6 ; write out entire mode line
- cmp flags.vtflg,0 ; emulating?
- je modl7 ; e = no
- and yflags,not modoff ; update local flags (mode line on)
- mov al,yflags ; Yes - update flags also
- call ansdsl ; get extras from emulator
- modl7: mov dx,cursor
- mov ah,2
- mov bh,0
- int screen ; put cursor back where it belongs
- ret
- modlin endp
-
- clrmod proc near ; clear mode line
- call trmatt ; Get terminal screen attributes
- mov bh,al ; Use screen background attribute
- mov ax,600h ; blank window
- mov dx,low_rgt ; right most column
- inc dh ; refer to status line
- mov cx,dx ; bottom line [dlk]
- xor cl,cl ; left most column
- ;**** Modify to suit CCDOS. June 25,1990 [zqf]
- mov ax,cx
- mov bx,dx
- call atsclr
- ; int screen ; clear mode line
- ;****
- or yflags,modoff ; turn on flag
- ret
- clrmod endp
-
-
- ; Fetch screen attributes from emulator (if emulating). It exists mainly
- ; so that the reverse video will work. Returns the current mode
- ; line background attribute in ah, the current screen background in al,
- ; and the current "cursor" (foreground) attribute in bl. (Note: anstat
- ; returns status yflags in bh).
-
- trmatt proc near ; Get attributes
- cmp flags.vtflg,0 ; emulating?
- je trmat1 ; No, just do simple stuff
- mov al,yflags ; anstat expects flags byte in al
- call anstat ; Fetch emulator status/attributes
- ret
- trmat1: mov al,scbattr ; Background attributes
- mov bl,curattr ; And cursor attribute
- mov ah,al ; where modlin needs them
- and ah,77h ; get colors part, no blink/bold
- rol ah,1 ; reverse them
- rol ah,1
- rol ah,1
- rol ah,1
- ret
- trmatt endp
-
- ; Get byte yflags of terminal emulator passed in AL. Used in mode line
- ; handling when 25th line is used by the emulator. [jrd]
- telmsy proc near
- mov yflags,al ; get the updated flags
- call ansflg ; and any other emulator info
- ret
- telmsy endp
-
-
- ;[IU2] This routine updates the ANSI status flags from the emulator,
- ; and passes the "yflags" byte to the VT100 emulator also.
-
- ansflg proc near
- push ax ; save regs
- push bx
- mov al,yflags
- call anstat ; Get status and attributes
- mov ansflgs,bh ; Save
- test ansflgs,dececho ; does host want us to do local echo?
- jz ansflg1 ; z = no, use working default
- or yflags,lclecho ; turn on local echoing
- ansflg1:pop bx
- pop ax
- ret
- ansflg endp
-
- getflgs proc near ; supply yflags for terminal emulators
- mov al,yflags
- ret
- getflgs endp
-
- term proc near ; terminal mode entry point
- mov argadr,ax ; save argument ptr
- call argini ; init options from arg address
- call scrini ; init screen stuff
- mov bx,portval ; port data structure address
- mov bx,[bx].flowc ; get flow control chars (bl=xoff)
- mov flowon,bh
- mov flowoff,bl ; save for later
- mov oldsp,sp ; remember stack for i/o failure,
- ; used by procedure endcon
- lp: call prtchr ; char at port?
- jmp short lpinp ; yes, go handle
- nop ; else look at kbd
- lpkbd: mov fairness,0 ; say kbd was examined
- call keybd ; call keyboard translator in msu
- jnc lp ; nc = no char or have processed it
- jmp short quit ; carry set = quit connect mode
- lpinp: and al,parmsk ; apply 8/7 bit parity mask
- call outtty ; print on terminal
- inc fairness ; say read port but not kbd, again
- cmp fairness,100 ; this many port reads before kbd?
- jb lp ; b = no, read port again
- jmp short lpkbd ; yes, let user have a chance too
-
- quit:
- call pntflsh ; flush printer buffer
- call tekend ; cleanup Tektronix mode [bjh]
- mov ah,3 ; get cursor position into dx
- xor bh,bh ; page 0
- int screen
- mov cursor,dx ; save position
- cmp flags.vtflg,0 ; terminal type of none?
- ja quit1 ; a = yes
- test yflags,modoff ; is modeline still toggled off?
- jnz quit1 ; nz = yes
- call clrmod ; clear it before storing screen
- quit1: nop
- ;******************
- call savescr ; save screen in MS-DOS
- ;*******************
- mov ax,0600h ; clear mode line with old attributes
- mov bh,oldattr ; attributes
- mov dx,low_rgt ; right most column
- inc dh ; refer to status line
- mov cx,dx ; bottom line [dlk]
- xor cl,cl ; left most column
- ;**** Modify to suit CCDOS. June 25,1990 [zqf]
- mov ax,cx
- mov bx,dx
- call atsclr
- ; int screen ; clear mode line
- ;****
- mov ah,oldattr ; attributes at init time
- mov scbattr,ah ; background = original state
- ; for ega in non-standard # lines
- cmp ega_mode,0 ; ega board active?
- je quit2 ; e = no
- cmp byte ptr low_rgt+1,23 ; is screen standard length?
- je quit2 ; e = yes, so regular cursor set is ok
- push es ; turn off ega cursor emulation
- mov ax,40h ; byte 40:87H is ega Info byte
- mov es,ax
- push es:[87h] ; save info byte around call
- or byte ptr es:[87h],1 ; set emulation off (low bit = 1)
- mov cx,lincur ; cursor shape to set
- mov ah,1 ; set the shape
- int screen ; back to starting value
- pop es:[87h] ; recover original Info byte
- pop es ; and our work reg
- jmp short quit3 ; skip regular mode cursor setting
- quit2: ; for regular sized screen
- mov cx,lincur ; cursor type at startup
- mov ah,1
- int screen ; restore cursor type
- quit3: mov ah,2 ; Position cursor
- mov bh,0 ; Page 0
- mov dx,low_rgt ; bottom line
- inc dh ; status line position
- xor dl,dl ; left most column
- ; ---------don't set cursor in CCDOS. Dec.12,1990 [zqf]
- IFDEF CGA ; Add Option CGA to servered screen.Mar.21,1991 [zqf]
- cmp isccdos,1 ; is in CCDOS ?
- je quit4 ; e = yes, skip
- ENDIF
- int screen ; Do it
- quit4:
- ; -----------
- mov al,yflags
- and al,not lclecho ; don't copy host's echo flag
- mov bx,argadr
- mov ah,[bx].flgs ; get user's flag settings
- and ah,lclecho ; clear all but local echo bit
- or [bx].flgs,al ; update flags in arg block
- ret
- term endp
-
- ; put the character in al to the screen
- outtty proc near
- cmp flags.vtflg,0 ; emulating a terminal?
- jne outnoc ; ne = yes, emulator handles printing
- test flags.remflg,d8bit ; keep 8 bits for displays?
- jnz outnp9 ; nz = yes, 8 bits if possible
- and al,7fh ; remove high bit
- outnp9: cmp rxtable+256,0 ; translation turned off?
- je outnp7 ; e = yes, no translation
- push bx
- mov bx,offset rxtable ; address of translate table
- xlatb ; new char is in al
- pop bx
- outnp7: test anspflg,prtscr ; should we be printing?
- jz outnop ; no, keep going
- call pntchr ; queue char for printer
- jnc outnop ; nc = successful print
- push ax
- call beep ; else make a noise and
- call trnprs ; turn off printing
- pop ax
- outnop: test yflags,capt ; capturing output?
- jz outnoc ; no, forget this part
- push ax ; save char
- call captrtn ; give it captured character
- pop ax ; restore character and keep going
- outnoc: cmp vtroll,0 ; auto roll back allowed?
- jz outnp6 ; z = no, leave screen as is
- cmp tekflg,0 ; Tek mode active?
- jne outnp6 ; ne = yes, skip screen rolling
- cmp bwnd.lcnt,0 ; is screen rolled back? [dlk]
- je outnp6 ; e = no
- ; ---------don't set cursor in CCDOS. Dec.12,1990 [zqf]
- IFDEF CGA ; Add Option CGA to servered screen.Mar.21,1991 [zqf]
- cmp isccdos,1 ; is in CCDOS ?
- je outnpa ; e = yes, skip
- ENDIF
- call endwnd ; restore screen before writing [dlk]
- outnpa:
- ; -----------
- outnp6: cmp flags.vtflg,0 ; emulating a terminal?
- jne outnop1 ; ne = yup, go do something smart
- test yflags,trnctl ; debug? if so use Bios tty mode
- jz outnp4 ; z = no
- mov ah,biostty ; Bios tty screen write
- cmp al,7fh ; Ascii Del char or greater?
- jb outnp1 ; b = no
- je outnp0 ; e = Del char
- push ax ; save the char
- mov al,7eh ; output a tilde for 8th bit
- int screen
- pop ax ; restore char
- and al,7fh ; strip high bit
- outnp0: cmp al,7fh ; is char now a DEL?
- jne outnp1 ; ne = no
- and al,3fH ; strip next highest bit (Del --> '?')
- jmp outnp2 ; send, preceded by caret
- outnp1: cmp al,' ' ; control char?
- jae outnp3 ; ae = no
- add al,'A'-1 ; make visible
- outnp2: push ax ; save char
- mov al,5eh ; caret
- int screen ; display it
- pop ax ; recover the non-printable char
- outnp3: push ax
- int screen
- pop ax
- ret
- outnp4: cmp al,bell ; bell (Control G)?
- jne outnp5 ; ne = no
- jmp beep ; use short beep, avoid char loss
- outnp5: mov dl,al ; write without intervention
- mov ah,conout
- int dos ; else let dos display char
- ret
-
- outnop1:cmp flags.vtflg,tttek ; doing Tektronix emulation?
- je outnop2 ; e = yes, use Tek emulator
- cmp tekflg,0 ; Tek submode active?
- jne outnop2 ; ne = yes, use Tek emulator
- jmp anstty ; call terminal emulator routine & ret
- outnop2:jmp tekemu ; use Tek emulator and return
-
- outtty endp
-
- ;[IU2] Here to output character to port with no echo (like escape sequences
- ; sent by PF keys, responses to requests from the host, etc. It is
- ; wrong thinking to echo these).
-
- prtbout proc near ; Global routine now
- mov ah,al ; This is where outchr expects it
- call outchr
- jmp endcon ; failure, end connection
- nop
- clc ; carry clear for success
- ret
- prtbout endp
-
-
- ;[IU2] Here to output an unsigned 8-bit number (in al) to the port without
- ; echoing. Used by terminal emulator escape sequence output.
-
- prtnout proc near
- mov bl,10 ; Output in base 10
- jmp prtno2 ; Ensure at least a zero
-
- prtno1: cmp al,0
- jne prtno2 ; Yes - do more digits
- ret ; No - return from recursive call
- prtno2: mov ah,0 ; Clear previous remainder
- div bl ; Divide off a digit
- push ax ; Push remainder (in ah) on stack
- call prtno1 ; Recur
- pop ax ; Pop off a digit
- add ah,'0' ; Make it ASCII
- call outchr ; send to port
- jmp endcon ; failure, end connection
- nop
- clc ; carry clear for success
- ret
- prtnout endp
-
- ; send the character in al out to the serial port; handle echoing.
- ; Can send an 8 bit char while displaying only 7 bits locally.
- outprt proc near
- test yflags,lclecho ; echoing?
- jz outpr1 ; z = no, forget it
- push ax ; save char
- call outtty ; print it
- pop ax ; restore
- outpr1: mov ah,al ; this is where outchr expects it
- call outchr ; output to the port
- jmp endcon ; failure, end connection
- nop
- clc ; carry clear for success
- ret
- outprt endp
-
- ; Jump here to exit Connect mode and execute macros 'TERMINALR' (vtrmac) or
- ; 'TERMINALS' (vtsmac). Does nothing if macro does not exist.
- ; Preserves registers except ax. Returns to TELNET caller with 'C' in kbdflg.
- vtrmac proc near ; RESET macro
- mov ax,offset vtrname ; select macro name
- mov vtmacname,ax
- mov vtmaclen,vtrlen ; and its length
- jmp short vtmacro ; finish in common code
- vtrmac endp
-
- vtsmac proc near ; SET macro
- mov ax,offset vtsname
- mov vtmacname,ax
- mov vtmaclen,vtslen
- jmp short vtmacro
- vtsmac endp
-
- ;
- ; Reference Macro structure for db number of entries (mac names)
- ; is file table mcctab |-> db length of macroname, excl '$'
- ; mssset.asm each entry |-> db 'macroname','$'
- ; where these |-> dw offset of definition string
- ; are stored.
- ; Definition string in db length of <string with null>
- ; buffer macbuf db 'string with trailing null'
- ;
- vtmacro proc near ; common code for macros vtsmac,vtrmac
- push bx
- push cx
- push si
- mov bx,offset mcctab ; table of macro names
- mov cl,[bx] ; number of names in table
- xor ch,ch
- jcxz vtmacx ; z = empty table, do nothing
- inc bx ; point to length of first name
- vtmac2: mov al,[bx] ; length of this name
- xor ah,ah
- cmp al,vtmaclen ; length same as desired keyword?
- jne vtmac3 ; ne = no, search again
- mov si,bx
- inc si ; point at first char of name
- push cx ; save name counter
- push di ; save reg
- mov cl,vtmaclen ; length of name, excluding '$'
- xor ch,ch
- mov di,vtmacname ; point at desired macro name
- push es ; save reg
- push ds
- pop es ; make es use datas segment
- cld
- repe cmpsb ; match strings
- pop es ; need current si below
- pop cx
- pop di ; recover saved regs
- je vtmac4 ; e = matched
- vtmac3: add bx,ax ; step to next name, add name length
- add bx,4 ; + count, dollar sign, def word ptr
- loop vtmac2 ; try next name
- vtmacx: pop si ; no macro, return to Connect mode
- pop cx
- pop bx
- ret
-
- vtmac4: cmp taklev,maxtak ; room in Take level?
- jge vtmacx ; ge = no, exit with no action
- inc taklev ; increment take level
- add takadr,size takinfo ; make a new Take entry/macro
- mov bx,takadr ; point to current macro structure
- inc si ; skip dollar sign after name
- mov si,[si] ; get definition address
- mov [bx].takbuf,si ; address of definition string struc
- mov cl,[si] ; length byte of definition
- xor ch,ch
- mov [bx].takcnt,cx ; number of chars in definition
- inc si ; address of definition text proper
- mov [bx].takptr,si ; where to read next command char
- mov [bx].taktyp,0ffh ; flag as a macro
- pop si
- pop cx
- pop bx
- jmp endcon ; exit Connect mode
- vtmacro endp
-
- ; Error recovery routine used when outchr reports unable to send character
- ; or when vtmacro requests exiting Connect mode.
- ; Exit Connect mode cleanly, despite layers of intermediate calls.
- endcon proc near
- mov kbdflg,'C' ; report 'C' to TERM's caller
- mov sp,oldsp ; recover startup stack pointer
- ; TERM caller's return address is now
- ; on the top of stack. A longjmp.
- jmp quit ; exit Connect mode cleanly
- endcon endp
-
- ;;; Action routines (verbs) for keyboard translator KEYBD in msuibm.
- ; These are invoked by a jump instruction. Return carry clear for normal
- ; processing, return carry set for invoking Quit (kbdflg has transfer char).
- uparrw: mov al,'A' ; cursor keys
- jmp short comarr
- dnarrw: mov al,'B'
- jmp short comarr
- rtarr: mov al,'C'
- test vtemu.vtflgop,vswdir ; writing left to right?
- jz comarr ; z = yes
- mov al,'D' ; reverse sense of keys
- jmp short comarr
- lfarr: mov al,'D'
- test vtemu.vtflgop,vswdir ; writing left to right?
- jz comarr ; z = yes
- mov al,'C' ; reverse sense of keys
- comarr: push ax ; save final char
- mov ttyact,0 ; network, group chars for packet
- mov al,escape ; Output an escape
- call outprt ; Output, echo permitted
- cmp flags.vtflg,tttek ; Tek terminal?
- je comar0 ; e = yes, use VT100 codes
- cmp flags.vtflg,ttvt100 ; VT100 terminal emulation?
- jne comar2 ; No, do VT52/HEATH-19 sequence
- comar0: call ansflg ; Update flags all around
- mov al,'[' ; Maybe this next?
- test ansflgs,decckm ; Cursor key mode reset?
- je comar1 ; Yes, output the "["
- mov al,'O' ; No, set, use the "O"
- comar1: call outprt ; Output it (echo permitted)
- comar2: pop ax ; recover final char
- mov ttyact,1 ; network, restore tty active flag
- call outprt ; Output to port (echo permitted)
- ret
-
- pf1: mov al,'P' ; keypad function keys 1-4
- jmp short compf
- pf2: mov al,'Q'
- jmp short compf
- pf3: mov al,'R'
- jmp short compf
- pf4: mov al,'S'
- compf: push ax ; save final char
- mov ttyact,0 ; network, group chars for packet
- mov al,escape ; Output an escape
- call prtbout
- call ansflg ; get emulator flags
- test ansflgs,decanm ; ansi mode?
- jz short compf1 ; z = no
- mov al,'O' ; send an "O"
- call prtbout ; Output it
- compf1: pop ax ; Get the saved char back
- mov ttyact,1 ; network, restore tty active flag
- call prtbout ; Output to port
- ret
-
- kp0: mov al,'p' ; keypad numeric keys
- jmp short comkp
- kp1: mov al,'q'
- jmp short comkp
- kp2: mov al,'r'
- jmp short comkp
- kp3: mov al,'s'
- jmp short comkp
- kp4: mov al,'t'
- jmp short comkp
- kp5: mov al,'u'
- jmp short comkp
- kp6: mov al,'v'
- jmp short comkp
- kp7: mov al,'w'
- jmp short comkp
- kp8: mov al,'x'
- jmp short comkp
- kp9: mov al,'y'
- jmp short comkp
- kpminus:mov al,'m'
- jmp short comkp
- kpcoma: mov al,'l'
- jmp short comkp
- kpenter:mov al,'M'
- jmp short comkp
- kpdot: mov al,'n'
- comkp: test ansflgs,deckpam ; keypad application mode active?
- jnz comkp3 ; nz = yes, use escape sequences
- sub al,40h ; deduct offset to numeric symbols
- jmp comkp0 ; and send that single char
- comkp3: push ax ; save final char
- mov ttyact,0 ; network, group chars for packet
- mov al,escape ; Output an escape
- call prtbout
- mov al,'O' ; Output the "O"
- cmp flags.vtflg,ttvt100 ; VT100 mode?
- je comkp1 ; e = yes, use "O" code
- cmp flags.vtflg,tttek ; Tek terminal
- je comkp1 ; e = yes, use VT100 codes
- test ansflgs,decanm ; ANSI (alt application keypad) mode?
- jnz comkp1 ; nz = yes, use "O"
- comkp2: mov al,'?' ; else use "?" instead of "O"
- comkp1: call prtbout
- pop ax ; recover final char
- comkp0: mov ttyact,1 ; network, restore tty active flag
- call prtbout ; send it
- ret
-
- klogon proc near ; resume logging (if any)
- test flags.capflg,logses ; session logging enabled?
- jz klogn ; z = no, forget it
- or argadr.flgs,capt ; turn on capture flag
- or yflags,capt ; set local msy flag as well
- call ansflg ; tell emulator
- klogn: clc
- ret
- klogon endp
-
- klogof proc near ; suspend logging (if any)
- and argadr.flgs,not capt ; stop capturing
- and yflags,not capt ; reset local msy flag as well
- call ansflg ; tell emulator
- klogo: clc
- ret
- klogof endp
-
- snull proc near ; send a null byte
- mov al,0 ; the null
- jmp prtbout ; send without logging and local echo
- snull endp
-
- khold: xor holdscr,1 ; toggle Hold screen byte for msx
- clc
- ret
- ; general character out for emulator
- chrout: cmp flags.vtflg,0 ; emulating?
- je chrou5 ; e = no
- call anskbi ; Yes, say we had keyboard input
- cmp al,cr ; A CR?
- jne chrou5 ; No - just output it and return
- call ansflg ; Yes - update VT100 flags
- test ansflgs,anslnm ; ANSI new-line mode set?
- jz chrou5 ; No - just send the cr
- call outprt ; Yes - output a carriage-return
- mov al,lf ; Followed by a line feed
- chrou5: call outprt
- ret
-
- ; these commands invoke Quit
- cdos: mov al,'P' ; Push to DOS
- jmp short cmdcom
- cstatus:mov al,'S' ; Status
- jmp short cmdcom
- cquit: mov al,'C' ; Exit Connect mode
- jmp short cmdcom
- cquery: mov al,'?' ; Help
- jmp short cmdcom
- chang: mov al,'H' ; Hangup, drop DTR & RTS
- jmp short cmdcom
- cmdcom: mov kbdflg,al ; pass char to msster.asm via kbdflg
- stc ; signal that Quit is needed
- ret
-
- dmpscn proc near ; dump screen to file
- call savescr ; save screen to buffer
- call dumpscr ; do buffer to file
- clc ; do not exit Connect mode
- ret
- dmpscn endp
-
-
- ;[IU2] Routine to toggle VT100/VT52/Heath-19 modes in VT100 emulator.
-
- vtans52 proc near
- cmp flags.vtflg,0 ; emulating?
- je vtans5 ; e = no
- call ans52t ; Call MSZ toggle-it routine
- call ansflg ; Update flags
- clc ; clear c bit so don't exit Connect
- vtans5: ret
- vtans52 endp
- ; Toggle Mode Line
- trnmod: cmp flags.modflg,1 ; mode line enabled and owned by us?
- jne trnm2 ; ne = no, don't touch it
- cmp flags.vtflg,tttek ; Tek mode?
- je trnm2 ; yes
- cmp tekflg,0 ; Tek submode?
- jne trnm2 ; ne = yes, no mode line changes
- test yflags,modoff ; mode line already off?
- jnz trnm1 ; yes, go turn on
- call clrmod ; no, clear mode line here
- or yflags,modoff ; turn on flag
- call ansflg ; Update flags all around
- clc ; clear c bit so don't exit Connect
- ret
- trnm1: and yflags,not modoff ; Clear flag first
- cmp flags.vtflg,0 ; terminal type of none?
- ja trnm3
- push dx ; scroll screen to save bottom line
- mov ah,prstr ; for terminal type none
- mov dx,offset crlf
- int dos
- pop dx
- trnm3: call modlin ; Then turn on mode line
- call ansflg ; Update flags all around
- trnm2: clc
- ret
-
- trnprs: push ax ; toggle ^ PrtSc screen to printer
- test anspflg,prtscr ; are we currently printing?
- jnz trnpr2 ; nz = yes, its on and going off
- mov ah,ioctl
- mov al,7 ; get output status of printer
- push bx
- mov bx,4 ; file handle for system printer
- int dos
- pop bx
- jc trnpr1 ; c = printer not ready
- cmp al,0ffh ; Ready status?
- je trnpr2 ; e = Ready
- trnpr1: call beep ; Not Ready, complain
- jmp trnpr3 ; and ignore request
- trnpr2: xor anspflg,prtscr ; flip the flag
- test yflags,modoff ; mode line off?
- jnz trnpr3 ; nz = yes
- call modlin ; else rewrite mode line
- trnpr3: pop ax
- clc ; return carry clear (don't quit)
- ret
-
- ; Print on PRN the char in register al. On success return with C bit clear.
- ; On failure do procedure pntchk and return its C bit (typically C set).
- ; Uses buffer dumpbuf (screen dump).
- pntchr proc near
- push bx ; buffer the character
- mov bx,pntptr ; offset of next free byte in buffer
- mov [bx],al ; store the character
- inc bx ; update pointer
- mov pntptr,bx ; save pointer
- cmp bx,offset dumpbuf+dumplen ; buffer full yet?
- pop bx
- jb pntchrx ; b = no, just return
- jmp pntflsh ; go flush the buffer
- pntchrx:clc ; clear carry bit
- ret
- pntchr endp
-
- ; Flush printer buffer. Return carry clear if success.
- ; On failure do procedure pntchk and return its C bit (typically C set).
- ; Uses buffer dumpbuf (screen dump).
- pntflsh proc near
- cmp pntptr,offset dumpbuf ; any text in buffer?
- jne pntfls1 ; ne = yes
- ret ; else nothing to do
- pntfls1:push ax
- push bx
- push cx
- push dx
- mov bx,portval
- mov bx,[bx].flowc ; get flow control chars (bl=xoff)
- mov flowon,bh
- mov flowoff,bl ; save for later
- mov al,bl ; get flow control char
- cmp al,0 ; flow control active?
- je pntfls2 ; e = no, not using xoff
- call prtbout ; output xoff (al), no echo
- pntfls2:mov ah,write2
- mov bx,4 ; file handle for DOS printer PRN
- mov cx,pntptr ; next free byte in buffer
- mov dx,offset dumpbuf ; start of buffer
- mov pntptr,dx ; reset buffer pointer
- sub cx,dx ; cx = current byte count
- jcxz pntfls3 ; z = empty, do nothing
- int dos ; write buffer to printer
- pntfls3:pushf ; save carry status bit
- mov al,flowon
- cmp al,0 ; flow control active?
- je pntfls4 ; e = no, not using xon
- call prtbout ; output xon (al), no echo
- pntfls4:popf
- pop dx
- pop cx
- pop bx
- pop ax
- jnc pntflsx ; nc = success
- call pntchk ; c = error (printer not ready)
- pntflsx:ret
- pntflsh endp
-
- ; Check for PRN (DOS's printer) being ready. If ready, return with C clear
- ; Otherwise, write Not Ready msg on mode line and return with C bit set.
- ; N.B. DOS Critical Error will occur here if PRN is not ready. [jrd]
- pntchk proc near
- push dx
- push cx
- push ax
- mov cx,10 ; ten retries before declaring error
- pntchk0:mov ah,ioctl ; get printer status, via DOS
- mov al,7 ; status for output
- push bx
- mov bx,4 ; std handle for DOS system printer
- int dos
- pop bx
- jc pntchk1 ; c = call failed
- cmp al,0ffh ; code for Ready?
- je pntchk3 ; e = yes, assume printer is ready
- pntchk1:push cx ; save counter, just in case
- mov ax,100 ; wait 100 millisec
- call pcwait
- pop cx
- loop pntchk0 ; and try a few more times
- ; get here when printer is not ready
- test yflags,modoff ; is mode line off?
- jnz pntchk2 ; nz = off, skip msg
- push bx
- push si
- ; mov si,offset pntmsg ; say printer not ready
- mcmsgsi pntmsg, cpntmsg
- mov cx,pntmsgl ; length
- cmp isccdos,0
- je pntchk11
- mov cx,cpntmsgl
- pntchk11:
- call modwrt ; write alternate mode line
- pop si
- pop bx
- pntchk2:pop ax
- pop cx
- pop dx
- stc ; say printer not ready
- ret
- pntchk3:pop ax
- pop cx
- pop dx
- clc ; say printer is ready
- ret
- pntchk endp
-
- ;;;;; General screen management routines for IBM PC
-
- ; computes screen location to ax, given row and col in [dh,dl], resp.
-
- scrloc proc near
- mov al,dh ; get row
- mul crt_cols ; multiply by number of columns
- add al,dl ; plus current column number
- adc ah,0 ; ripple carry
- shl ax,1 ; double for attributes
- ret
- scrloc endp
-
- ; Routine to set cursor type. Pass cursor type in al: 0 = No cursor,
- ; 1 = Underline cursor, 2 = Block cursor. All cursors blink due to hardware.
- ; Routine frags any ac that video ints frag.
- ; For EGA boards running in non-25 line mode the cursor emulation is turned
- ; off during cursor shape changing and restored afterward. It's another
- ; ega Feature. [jrd]
- ; Sense crt_mode 18h as Tseng Labs UltraPAK mono board in 132 column mode.
- csrtype proc near
- push cx ; save the reg
- mov ah,1 ; Video fxn for set cursor type
- mov cx,0F00H ; Assume no cursor
- cmp al,0 ; No cursor?
- je csrty2 ; Right - set it and be done with it
- cmp crt_mode,7 ; B&W card?
- je csrty3 ; Yes - different sizes
- cmp crt_mode,18h ; Tseng UltraPAK mono board?
- je csrty3 ; e = yes, use mono cursor
- mov cx,0607H ; No, use CGA underline cursor
- cmp al,2 ; Block?
- jne csrty2 ; No - set it now
- csrty1: xor ch,ch ; Yes - make it a block
- csrty2: cmp ega_mode,0 ; ega board active?
- je csrty4 ; e = no
- cmp byte ptr low_rgt+1,23 ; standard screen length?
- je csrty4 ; e = yes, use regular cursor setting
- push es ; EGA. turn off cursor emulation
- mov ax,40h ; 40:87h is ega Info byte
- mov es,ax
- push es:[87h] ; save Info byte around call
- or byte ptr es:[87h],1 ; set emulation off (low bit = 1)
- mov ah,1 ; Video fxn for set cursor type
- int screen
- pop es:[87h] ; restore Info byte
- pop es ; and our work register
- pop cx
- ret
- csrty4: int screen ; regular cursor shape setting
- pop cx
- ret
- csrty3: mov cx,0B0CH ; Assume B&W underline cursor
- cmp al,2 ; Block?
- jne csrty2 ; No - set it now
- jmp csrty1 ; Yes - make it a block
- csrtype endp
-
-
- ; Save the entire screen in a buffer so we can restore and/or dump it.
- ; Saves regular (80x25) screens to memory buffer scrsav and other sized
- ; screens to video memory page 1. Resultant save place put into savadr
- ; (offset then segment) and current low_rgt size info in savflg. Note,
- ; some Environments (TopView/Windows etc) may not permit use of page 1. [jrd]
- savescr proc near
- push es
- push ds
- push ax
- push cx
- push si
- push di
- ; ****************** if in CC-DOS mode? Nov.1990 [zqf]
- cmp isccdos,1 ; if CC-DOS ?
- jne savsc0 ; ne = No.
- IFNDEF CGA ; Add Option CGA to servered screen.Mar.21,1991 [zqf]
- call savccscr ; yes, call CCDOS screen save proc
- ENDIF
- jmp savsc4 ; return
- savsc0:
- ; **********************
- call scrseg ; get screen segment in ax and es:di
- push ax ; save screen segment
- mov si,0
- mov di,scrsav ; place to put screen (memory buff)
- mov savadr+2,di ; working seg address for restore
- mov savadr,0 ; and no offset for memory buffer
-
- call scrmod ; ascertain video mode and screen
- mov ax,low_rgt ; text screen lower right (typ 23,79)
- mov savflg,ax ; save it for screen restore
- inc al ; number of columns
- add ah,2 ; plus status line = number of rows
- cmp al,swidth ; same as preset screen space (80)?
- ja savsc1 ; a = no, use screen video page 1
- cmp ah,slen+1 ; same as preset screen length (24)?
- je savsc3 ; e = yes, use our memory buffer
- savsc1: mul ah ; times rows = characters on screen
- shl ax,1 ; times two for attributes = page 1
- mov cx,ax ; cx = working copy of screen size
- and cx,000fh ; get lower four bits for offset part
- mov savadr,cx ; save offset in this word
- mov cl,4
- shr ax,cl ; compute number of paragraphs
- pop di ; source screen address
- push di ; restore again
- add di,ax ; add paragraphs, point di to page 1
- mov savadr+2,di ; and save segment in this word
- savsc3:
- mov es,savadr+2 ; segment of storage area
- mov di,savadr ; offset of same
- mov ax,low_rgt ; lower right of text screen
- inc al ; number of columns on screen
- add ah,2 ; number of rows on screen
- mul ah ; number of characters on the screen
- mov cx,ax ; save this in counter cx
- call scroff ; turn off screen [dt]
- pop ds ; address screen
- cld
- rep movsw ; save the screen
- savsc4:
- pop di
- pop si
- pop cx
- pop ax
- pop ds ; restore this
- call scron ; turn on screen [dt]
- pop es
- ret
- savescr endp
-
- ; restore screen from buffer (offset and seg in savadr, text coord in savflg).
- ; Restores all screen lines. [jrd]
- restscr proc near
- ; ****************** if in CC-DOS mode? Nov.1990 [zqf]
- cmp isccdos,1 ; if CC-DOS ?
- jne rstscr0 ; ne = No.
- IFNDEF CGA ; Add Option CGA to servered screen.Mar.21,1991 [zqf]
- call rstccscr ; yes, call CCDOS screen restore proc
- ENDIF
- ret ; return
- rstscr0:
- ; **********************
- push es
- mov ax,savflg ; saved low_rgt text screen coord
- add ah,2 ; number of screen lines
- inc al ; number of screen columns
- mul ah ; columns time lines = # characters
- mov cx,ax ; save this in counter cx
- push cx ; save count
- call scrseg ; get address of screen in es:di
- call scroff ; turn off screen [dt]
- push ds ; save original data segment
- mov si,savadr ; offset of storage area
- push savadr+2 ; segment of same
- pop ds ; put storage segment into ds
- cld
- rep movsw ; restore data to screen
- pop ds ; recover original data segment
- call scron ; turn on screen [dt]
- pop cx ; recover count
- call scrsync ; synch Topview with new screen
- pop es
- ret
- restscr endp
-
- ;**************************** used in CC-DOS Nov.28,1990 [zqf]
- ; SAVCCSCR ---- called by <savescr> of module "ccyibm.asm".
- ; which save screen char & attr in buffer pointed
- ; by scrsav in CC-DOS. Nov 28,1990 [zqf]
- ; All registers are reserved.
- ;********************************
-
- SAVCCSCR proc near
- push ax
- push bx
- push cx
- push dx
- push di
- push es
-
- mov ax,scrsav ; buffer segment address, offset is zero
- mov es,ax
- mov di,0
- mov savadr+2,es
- mov savadr,di
- ; read current cursor
- mov bh,0
- mov ah,3
- int 10h ; read current cursor pos. & type.
- mov curpos,dx ; saved in <curattr>
- mov curtyp,cx ;
- ; save screen
- mov bh,0
- mov dx,0
- savccscr1: mov ah,2
- int 10h ; set cursor position <DH,DL>---<row,col>
- mov ah,8
- int 10h ; read char & attr in current cursor pos.
- mov es:[di],ax ; save in scrbuf
- inc dl
- cmp dl,crt_cols ; crt_cols:number of screen cols (typ 80)
- jl savccscr2
- mov dl,0
- inc dh
- cmp dh,crt_lins ; crt_lins:number of rows-1 (typ 24)
- jg savccscr3
- savccscr2:
- inc di
- inc di
- jmp savccscr1
- savccscr3:
- pop es
- pop di
- pop dx
- pop cx
- pop bx
- pop ax
- ret
- SAVCCSCR endp
- ;*******************************
-
- ;**************************** used in CC-DOS Nov.28,1990 [zqf]
- ; RSTCCSCR ---- called by <restscr> of module "ccyibm.asm".
- ; which restore screen char & attr in buffer pointed
- ; by savadr in CC-DOS. Nov 28,1990 [zqf]
- ; All registers are reserved.
- ;********************************
- RSTCCSCR proc
- push ax
- push bx
- push cx
- push dx
- push di
- push es
- mov ax,savadr+2 ; segment address of buffer
- mov es,ax
- mov di,savadr ; offset address of buffer
- ; restore screen
- mov bh,0
- mov dx,0
- rstccscr1:mov ah,2
- int 10h ; set cursor position <DH,DL>---<row,col>
- mov ax,es:[di] ; restore from scrbuf
- mov bl,ah
- mov cx,1
- mov ah,9
- int 10h ; write char & attr in current cursor pos.
- inc dl
- cmp dl,crt_cols ; crt_cols:number of screen cols (typ 80)
- jl rstccscr2
- mov dl,0
- inc dh
- cmp dh,crt_lins ; crt_lins:number of rows-1 (typ 24)
- jg rstccscr3
- rstccscr2:
- inc di
- inc di ; adjust pointer
- jmp rstccscr1
- rstccscr3:
- ; set original cursor pos &type
- mov bh,0
- mov cx,curtyp
- mov ah,1
- int 10h ; build cursor type
- mov bh,0
- mov dx,curpos
- mov ah,2
- int 10h ; set original cursor pos.
- pop es
- pop di
- pop dx
- pop cx
- pop bx
- pop ax
- ret
- RSTCCSCR endp
- ;********************************
-
-
-
- ; Save the screen to a buffer and then append buffer to a disk file. [jrd]
- ; Default filename is Kermit.scn; actual file can be a device too. Filename
- ; is determined by mssset and is passed as pointer dmpname.
- ; Dumpscr reads the screen image saved by savescr so call savescr call first.
-
- dumpscr proc near
- push ax
- push bx
- push cx
- push dx
- mov dmphand,-1 ; preset illegal handle
- mov dx,offset dmpname ; name of disk file, from mssset
- mov ax,dx ; where isfile wants name ptr
- call isfile ; what kind of file is this?
- jc dmp5 ; c = no such file, create it
- test byte ptr filtst.dta+21,1fh ; file attributes, ok to write?
- jnz dmp0 ; nz = no.
- mov al,1 ; writing
- mov ah,open2 ; open existing file
- int dos
- jc dmp0 ; c = failure
- mov dmphand,ax ; save file handle
- mov bx,ax ; need handle here
- mov cx,0ffffh ; setup file pointer
- mov dx,-1 ; and offset
- mov al,2 ; move to eof minus one byte
- mov ah,lseek ; seek the end
- int dos
- jmp dmp1
-
- dmp5: test filtst.fstat,80h ; access problem?
- jnz dmp0 ; nz = yes
- mov ah,creat2 ; file did not exist
- mov cx,20h ; attributes, archive bit
- int dos
- mov dmphand,ax ; save file handle
- jnc dmp1 ; nc = ok
-
- dmp0: mov ah,3 ; get cursor position
- xor bx,bx ; page 0
- int screen
- push dx ; save it
- mov dh,byte ptr low_rgt+1 ; go to status line
- inc dh
- xor dl,dl ; left most column
- mov ah,2 ; position cursor
- int screen
- ; mov dx,offset dmperr ; say no can do
- mcmsg dmperr, cdmperr
-
- mov ah,prstr
- int dos
- pop dx ; get original cursor position
- mov ah,2 ; position cursor
- xor bx,bx ; page 0
- int screen
- pop dx
- pop cx
- pop bx
- pop ax
- clc
- ret
-
- dmp1: mov ah,ioctl ; is destination ready for output?
- mov al,7 ; test output status
- mov bx,dmphand ; handle
- int dos
- jc dmp0 ; c = error
- cmp al,0ffh ; ready?
- jne dmp0 ; ne = not ready
- push di ; read screen buffer, write lines
- push si
- push es
- mov cl,byte ptr low_rgt+1 ; number of lines - 2
- add cl,2 ; number of line on screen
- xor ch,ch
- mov si,savadr ; offset in storage area
- dmp2: push cx ; save outer loop counter
- mov es,savadr+2 ; get storage segment
- mov di,offset dumpbuf ; data segment memory
- mov cl,byte ptr savflg ; number of columns on screen - 1
- inc cl ; number of columns on screen
- xor ch,ch
- dmp3: mov ax,word ptr es:[si] ; read char + attribute
- mov byte ptr [di],al ; store just char, don't use es:
- inc si ; update pointers
- inc si
- inc di
- loop dmp3 ; do for each column
- std ; set scan backward
- mov cl,byte ptr savflg ; number of columns on screen - 1
- inc cl ; number of columns on screen
- xor ch,ch
- push es
- mov ax,ds
- mov es,ax ; set es to data segment for es:di
- mov di,offset dumpbuf ; start of line
- add di,cx ; plus length of line
- dec di ; minus 1 equals end of line
- mov al,' ' ; thing to scan over
- repe scasb ; scan until non-space
- cld ; set direction forward
- pop es
- jz dmp3a ; z = all spaces
- inc cx
- inc di
- dmp3a: mov word ptr [di+1],0A0Dh ; append cr/lf
- add cx,2 ; line count + cr/lf
- mov dx,offset dumpbuf ; array to be written
- mov bx,dmphand ; need file handle
- mov ah,write2 ; write the line
- int dos
- pop cx ; get line counter again
- jc dmp3b ; c = error
- loop dmp2 ; do next line
- mov dx,offset dumpsep ; put in formfeed/cr/lf
- mov cx,3 ; three bytes overall
- mov ah,write2 ; write them
- dmp3b: mov bx,dmphand ; file handle
- int dos
- mov ah,close2 ; close the file now
- int dos
- dmp6: pop es
- pop si
- pop di
- pop dx
- pop cx
- pop bx
- pop ax
- clc
- ret
- dumpscr endp
-
-
- ; Get CRT mode - returns mode in variable crt_mode,
- ; updates crt_cols and low_rgt.
- ; For EGA active it looks in Bios work memory 40:84H for number of rows. [jrd]
- scrmod proc near
- push ax
- push dx
- mov ah,15 ; Get current video state
- int screen
- mov crt_mode,al ; Store CRT mode value
- mov crt_cols,ah ; store # of cols
- mov dl,ah ; # of cols again
- mov dh,crt_lins ; and # of rows (constant from msster)
- cmp ega_mode,0 ; ega active?
- je scrmod4 ; e = no
- push es ; yes, permit different lengths
- mov ax,40h ; refer to 40:84h for # ega rows
- mov es,ax
- mov ah,es:[84h] ; get number of rows - 1 (typ 24)
- cmp ah,20 ; less than 20 rows?
- jb scrmod3 ; b = yes, ignore this length
- cmp ah,80 ; more than 80 rows?
- ja scrmod3 ; a = yes, ignore this length
- mov dh,ah ; use this length
- mov crt_lins,dh ; update our working constant
- scrmod3:pop es
- scrmod4:dec dl ; max text column, count from zero
- dec dh ; max text row, count from zero
- mov low_rgt,dx ; save away window address
- pop dx
- pop ax
- ret
- scrmod endp
-
-
- ; Get screen segment - returns screen segment in ax, and full address in es:di
-
- scrseg proc near
- xor di,di ; start at beginning of screen (0,0)
- mov ax,0B000H ; Assume B&W card
- cmp crt_mode,7 ; Is it?
- je scrse1 ; e = yes
- cmp crt_mode,18h ; Tseng UltraPAK mono in 132 col?
- je scrse1 ; e = yes, use seg B000H
- mov ax,0B800H ; No - video memory is here on color
- cmp crt_mode,12 ; graphics set?
- jb scrse1 ; b = no
- cmp crt_mode,18 ; end of ordinary 640x480 graphics
- ja scrse1 ; a = no, assume CGA segment
- mov ax,0A000H ; graphics
- scrse1: mov es,ax ; tell Topview our hardware address needs
- mov tv_segs,es ; save our hardware screen address
- mov tv_sego,di ; segment and offset form
- mov tv_mode,1 ; assume we're running under Topview
- mov ah,tvhere ; query Topview for its presence
- int screen
- mov ax,es ; get its new segment for screen work
- cmp ax,tv_segs ; same as hardware?
- jne scrse2 ; ne = no, we are being mapped
- cmp di,tv_sego ; check this too
- jne scrse2 ; ne = no too. Use TV's work buf as screen
- mov tv_mode,0 ; else no Topview or no mapping
- scrse2: mov tv_segs,es ; save segment
- mov tv_sego,di ; and offset
- ret
- scrseg endp
-
- ; Synchronize a Topview provided virtual screen buffer with the image
- ; seen by the user. Requires cx = number of words written to screen
- ; (char & attribute bytes) and es:di = ENDING address of screen write.
- ; Changes ax and di.
- scrsync proc near
- cmp tv_mode,0 ; Topview mode active?
- je scrsyn1 ; e = no, skip DOS call below
- sub di,cx ; backup to start byte (cx = words)
- sub di,cx ; after storing words to screen
- mov ah,tvsynch ; tell Topview we have changed screen
- int screen ; so user sees updated screen
- scrsyn1:ret
- scrsync endp
-
- ; The following two routines are used to turn off the display while we
- ; are reading or writing the screen in one of the color card modes.
- ; Turn screen off for (known) color card modes only. All regs preserved.
- ; Includes code for old procedure scrwait. 16 June 1987 [jrd]
- scroff proc near
- cmp refresh,0 ; slow refresh?
- jne scrofx ; ne = no wait
- cmp ega_mode,0 ; Extended Graphics Adapter in use?
- jne scrofx ; ne = yes, no waiting
- cmp tv_mode,0 ; Topview mode?
- jne scrofx ; ne = yes, no waiting
- cmp crt_mode,7 ; B&W card?
- jnb scrofx ; Yes - just return
- push ax ; Save ax and dx
- push dx
- mov dx,crt_status ; CGA: Wait for vertical retrace
- scrof1: in al,dx
- test al,disp_enb ; display enabled?
- jnz scrof1 ; yes, keep waiting
- scrof2: in al,dx
- test al,disp_enb ; now wait for it to go off
- jz scrof2 ; so can have whole cycle
- mov dx,crtmset ; Output to CRT mode set port
- mov al,25H ; This shuts down the display
- out dx,al ; Dumb, but card is too
- pop dx ; restore regs
- pop ax
- scrofx: ret
- scroff endp
-
-
- ; Turn screen on for (known) color card modes only
- ; All registers are preserved.
-
- scron proc near
- cmp refresh,0 ; slow refresh?
- jne scronx ; ne = no wait
- cmp ega_mode,0 ; Extended Graphics Adapter in use?
- jne scronx ; ne = yes, no waiting
- cmp tv_mode,0 ; Topview mode?
- jne scronx ; ne = yes, no waiting
- cmp crt_mode,7 ; B&W card?
- jnb scronx ; Yes - just return
- push ax ; Save ax, dx, and si
- push dx
- push si
- mov al,crt_mode ; Convert crt_mode to a word
- xor ah,ah
- mov si,ax ; Get it in a usable register
- mov al,msets[si] ; Fetch the modeset byte
- mov dx,crtmset ; This port
- out dx,al ; Flash it back on
- pop si ; restore regs
- pop dx
- pop ax
- scronx: ret
- scron endp
-
-
- ; Screen clearing routine. [IU]
- ;
- ; Call: ax/ coordinates of first screen location to be cleared.
- ; bx/ coordinates of last location to be cleared.
- ; Coord: ah = row [0-24], al = column [0-79]. Preserves all registers. [jrd]
-
- atsclr: push ax ; save regs
- push cx
- push dx
-
- CALL PATSCLR ; CALL PROC TO CLEAR LINE
-
- mov dx,bx ; Compute last screen offset in ax
- push ax
- call scrmod ; update column length
- pop ax ; scrmod zaps ax
- push ax
- call scrloc ; get screen start address in ax
- mov cx,ax ; Save it in cx for a minute
- pop dx ; Compute first screen offset in ax
- call scrloc
- sub cx,ax ; Compute number of locs to clear
- add cx,2
- sar cx,1 ; Make byte count a word count
- jle atscl2 ; If nothing to clear, then vamos
- push di ; save regs
- push es ; save es
- push ax ; save around call
- call scrseg ; Get address of screen in ax, es:di
- pop ax ; recover displacement
- add di,ax ; displacement memory address
- mov ah,scbattr ; Use current screen background attr
- mov al,' ' ; Use space for fill
- mov dl,byte ptr low_rgt ; line length - 1
- inc dl ; line length
- xor dh,dh
- ;;;;; cmp cx,dx ; Blanking a line or less??
- ;;;;; jg atscl1 ; No - make scroff disable display
- atscl1:
- ; call scroff ; Turn screen off if color card
- push cx ; save word count for Topview
- cld
- ; rep stosw ; Blit... (excuse PDP-10ese please)
- pop cx ; recover word count
- ; call scrsync ; synch Topview
- ; call scron ; Turn screen back on if color card
- pop es ; Restore segment register
- pop di ; And destination index
- atscl2: pop dx ; restore regs
- pop cx
- pop ax
- ret
-
- ; Screen clearing routine.Ver 2.00 Dec. 15,1989 [ZU]
- ; (Screen clearing by scroll whole bolck between <ah,al> and <bh,bl>
- ; Call ax/ corrdinates of upon left location to be cleared.
- ; <ah,al>--<row,col>
- ; bx/ corrdinates of down right location to be cleared.
- ; <bh,bl>--<row,col>
- ; Cord: ah=row [0-24], al = col [0-79]. Preserves all registers. [zqf]
-
- patsclr proc near
- push ax
- push bx
- push cx
- push dx
- push si
- push di
- ; check if clear block or a line ?
- cmp bh,ah
- jg patsclr_b ; le= clear a block more than one line
-
- ; clear a block in one line
- ; read screen mode
- patsclr_l:
- push ax
- push bx
- mov ah,15 ;state
- int video
- mov activepage,bh
- ; mov cols,ah
- pop bx
- pop ax
- ; save current cursor
- push ax
- push bx
- mov bh,activepage
- mov ah,readcur
- int video
- mov currow,dh
- mov curcol,dl
- mov curtype,cx
- pop bx
- pop ax
- ; compute number of chars to clear in cx
- push ax
- xor cx,cx
- mov dx,0
- patscl1: cmp bh,ah
- jle patscl2
- mov dl,80 ;cols
- sub dl,al
- add cx,dx
- xor al,al
- inc ah
- jmp patscl1
- patscl2: cmp bl,al
- jl patscl3
- sub bl,al
- mov bh,0
- add cx,bx
- inc cx
- patscl3: pop ax
- cmp cx,0
- jle patscl10
- ; set cursor at start location of clearing area
- mov dx,ax
- mov bh,activepage
- mov ah,setcur
- int video
- ; clear screen < CX__number of chars >
- mov al,' ' ;space
- mov bh,activepage
- mov bl,scbattr
- ; mov ah,writech ; ????? different with 'writeach'
- mov ah,writeach
- int video
-
- ; restore current cursor
- mov dh,currow
- mov dl,curcol
- mov bh,activepage
- mov ah,setcur
- int video
-
- patscl10:
- pop di
- pop si
- pop dx
- pop cx
- pop bx
- pop ax
- ret
-
- ; scroll window at location <ah,al> to <bh,bl>
- patsclr_b:
- mov cx,ax
- mov dx,bx
- mov bh,scbattr
- mov al,0
- mov ah,06h
- int video
- jmp patscl10
- patsclr endp
-
- ; Scrolling routines. vtscru scrolls up, vtscrd scrolls down 'scroll'
- ; rows. The top line is saved in the circular buffer before scrolling up.
- ; When running under an Environment control number of line positions moved
- ; to be less than scrolling region. [jrd]
- ; All registers are preserved.
-
- ; Screen-roll down. Move text down one line, for terminal emulator only.
-
- vtscrd: push ax ; Upgraded by [jrd]
- push bx
- push cx
- push dx
- mov ah,7 ; scroll down
- mov ch,mar_top ; top margin line
- mov cl,0 ; left most column
- mov dh,mar_bot ; bottom margin line
- mov dl,byte ptr low_rgt ; right most column
- mov bh,scbattr ; attributes
- mov bl,dh
- sub bl,ch ; region size - 1 line
- mov al,scroll ; number of lines to scroll, from msz
- vscrd1: cmp al,bl ; want to scroll more that than?
- jbe vscrd2 ; be = no
- push ax
- mov al,bl ; limit to region-1 for Windows
- int screen ; and do in parts
- pop ax
- sub al,bl ; get remainder
- jmp short vscrd1 ; do next part
- vscrd2: int screen ; scroll it down
- pop dx
- pop cx
- pop bx
- pop ax
- ret
-
- ; Screen scroll up one line (text moves up) for terminal emulator use.
- ; When running under an Environment control number of line positions moved
- ; to be less than scrolling region. [jrd]
-
- vtscru: push ax ; Upgraded by [jrd]
- push bx
- push cx
- push dx
- mov cl,scroll ; number of lines to scroll
- mov ch,0
- cmp cx,0
- jnz vscru0
- jmp vscru3 ; z = nothing to do
- vscru0:
- cmp mar_top,0 ; scrolling the top screen line?
- ja vscru2 ; a = no. don't save anything
- push si
- push di
- ;******** test for CCDOS. Dec.12,1990 [zqf]
- IFDEF CGA ; Add Option CGA to servered screen.Mar.21,1991 [zqf]
- cmp isccdos,1 ; if CCDOS ?
- je vscru1a ; e = yes, in CCDOS, skip
- ENDIF
- call scroff ; turn off color screen
- mov si,tv_sego ; screen offset for es:si
- mov bx,offset twnd ; put lines in top window buffer
- vscru1: push cx ; save count
- call putcirc ; put screen line in circular buffer
- pop cx
- loop vscru1 ; save 'scroll' number of lines
- call scron ; turn on screen again
- IFDEF CGA ; Add Option CGA to servered screen.Mar.21,1991 [zqf]
- vscru1a:
- ENDIF
- ;********
- pop di
- pop si ; now scroll the visible screen
- vscru2: mov ah,6 ; scroll up
- mov dh,mar_bot ; bottom row
- mov dl,byte ptr low_rgt ; right most column
- mov ch,mar_top ; top row of scrolling region
- mov cl,0 ; left most column
- mov bh,scbattr ; attributes
- mov bl,dh
- sub bl,ch ; region size - 1 line
- mov al,scroll ; number of lines to scroll, from msz
- vscru2a:cmp al,bl ; want to scroll more that than?
- jbe vscru2b ; be = no
- push ax
- mov al,bl ; limit to region - 1 for Windows
- ;******** test for CCDOS. Dec.12,1990 [zqf]
- IFDEF CGA ; Add Option CGA to servered screen.Mar.21,1991 [zqf]
- cmp isccdos,1 ; if CCDOS ?
- je vscru2c ; e = yes, in CCDOS, skip
- ENDIF
- int screen ; and do in parts
- IFDEF CGA ; Add Option CGA to servered screen.Mar.21,1991 [zqf]
- jmp vscru2d ; in MSDOS
- vscru2c:
- push dx
- mov dl,0dh
- mov ah,2
- int 21h
- mov dl,0ah
- mov ah,2
- int 21h
- pop dx
- vscru2d:
- ENDIF
- ;********
- pop ax
- sub al,bl
- jmp short vscru2a ; do next part
- vscru2b:
- ;******** test for CCDOS. Dec.12,1990 [zqf]
- IFDEF CGA ; Add Option CGA to servered screen.Mar.21,1991 [zqf]
- cmp isccdos,1 ; if CCDOS ?
- je vscru2e ; e = yes, in CCDOS, skip
- ENDIF
- int screen ; and do in parts
- IFDEF CGA ; Add Option CGA to servered screen.Mar.21,1991 [zqf]
- jmp vscru2f ; in MSDOS
- vscru2e:
- push dx
- mov dl,0dh
- mov ah,2
- int 21h
- mov dl,0ah
- mov ah,2
- int 21h
- pop dx
- vscru2f:
- ENDIF
- ;********
- vscru3: pop dx ; Restore the rest of the regs
- pop cx
- pop bx
- pop ax
- ret
-
- ;screen text roll up, version for manual scrolling only
-
- mscru: push ax ; Upgraded by [jrd]
- push bx
- push cx
- push dx
- push si
- push di
- cmp bwnd.lcnt,0 ; any lines in bottom window?
- je mscru2 ; e = no, so ignore request
- call scroff ; turn off color screen
- mov bx,offset twnd ; this is where it goes
- mov si,tv_sego ; screen offset for es:si
- call putcirc ; put screen line in circular buffer
- mov ax,601H ; scroll up one line
- mov dx,low_rgt ; lower right corner
- xor cx,cx ; top row of scrolling region
- mov bh,scbattr ; background attributes
- int screen ; scroll up that region
- mov dx,low_rgt
- mov dl,0 ; location is lower left corner
- call scrloc ; get count from display start
- mov di,ax
- push es
- mov bx,tv_segs ; get screen's segment into, es:di
- mov es,bx ; segment
- add di,tv_sego ; destination memory address (es:di)
- mov bx,offset bwnd ; source of lines
- call getcirc ; get line from circ buf to screen
- pop es ; restore es
- call scron ; turn on the screen
- mscru2: pop di ; Restore the rest of the regs
- pop si
- pop dx
- pop cx
- pop bx
- pop ax
- ret
-
-
- ;screen text scroll down, for manual mode only
- mscrd: push ax ; Upgraded by [jrd]
- push bx
- push cx
- push dx
- push si
- push di
- cmp twnd.lcnt,0 ; any lines left in top window?
- je mscrd1 ; e = no, ingore request
- call scroff ; turn off screen
- mov dx,low_rgt ; from screen location, row
- mov dl,0 ; starting in col 0
- call scrloc ; get offset in display buffer in ax
- mov si,tv_sego ; screen offset for es:di
- add si,ax ; source addr in display buffer es:si
- mov bx,offset bwnd ; buffer to use (bottom window)
- call putcirc ; copy bottom screen line to circ buf
- mov ax,701H ; scroll down one line
- xor cx,cx ; top left corner
- mov dx,low_rgt ; bottom right corner
- mov bh,scbattr ; attributes
- int screen ; scroll it down
- push es
- mov di,tv_segs ; screen segment
- mov es,di
- mov di,tv_sego ; screen offset, for es:di
- mov bx,offset twnd ; buffer to use (top window)
- call getcirc ; copy from circ buf to screen
- pop es
- call scron ; turn on display again
- mscrd1: pop di ; Restore the rest of the regs
- pop si
- pop dx
- pop cx
- pop bx
- pop ax
- ret
-
- ; move viewing window down as much as possible (text moves up)
- endwnd proc near ; go to end of scrolling text
- push cx
- mov cx,bwnd.lcnt ; all bottom window lines [dlk]
- jmp dnwp0 ; and enter dwnpg
- endwnd endp
-
- dnone proc near ; move text up one line [jrd]
- push cx
- mov cx,1
- jmp dnwp0
- dnone endp
-
- ; scroll viewing window down (text moves up) one page (24 lines)
- dnwpg proc near
- push cx
- mov cl,byte ptr low_rgt+1 ; number of rows, excl status
- inc cl ; count from 1, not 0
- mov ch,0
- dnwp0: ; additional entry point
- cmp bwnd.lcnt,cx ; enough lines in bottom line buffer?
- jge dnwp1 ; ge = we have that many lines stored
- mov cx,bwnd.lcnt ; do as many as we have
- dnwp1: jcxz dnwp2 ; z = nothing to do
- cmp tekflg,0 ; Tek mode active?
- jne dnwp2 ; ne = yes, no scrolling
- call mscru ; scroll up text one line
- loop dnwp1
- dnwp2: pop cx
- clc
- ret
- dnwpg endp
-
- ; home viewing window
- homwnd proc near
- push cx
- mov cx,twnd.lcnt ; all top window lines [dlk]
- jmp upwp0 ; join upwpg
- homwnd endp
-
- upone proc near ; move text down one line [jrd]
- push cx
- mov cx,1
- jmp upwp0
- upone endp
-
- ; scroll viewing window up (text moves down) a page (24 lines)
- upwpg proc near
- push cx
- mov cl,byte ptr low_rgt+1 ; number of rows, excl status line
- inc cl ; count from 1, not 0
- mov ch,0
- upwp0: ; additional entry point
- cmp twnd.lcnt,cx ; enough lines in top line buffer?
- jae upwp1 ; ae = at least as many as requested
- mov cx,twnd.lcnt ; do only as many as are stored
- upwp1: jcxz upwp2 ; z = no lines to scroll
- cmp tekflg,0 ; Tek mode active?
- jne upwp2 ; ne = yes, no scrolling
- call mscrd ; roll down text one line
- loop upwp1
- upwp2: pop cx
- clc
- ret
- upwpg endp
-
-
- ; Put a line into the circular buffer. Pass the buffer structure in bx.
- ; Source is tv_segs:si which is the current screen address.
- ; Rewritten by [jrd]
- putcirc proc near
- push es
- mov cl,crt_cols ; number of columns
- xor ch,ch
- mov es,[bx].orig ; get segment of memory area
- cmp bx,offset bwnd ; bottom buffer?
- je putci6 ; e = yes
- mov di,twnd.pp ; pick up buffer ptr (offset from es)
- add di,cx ; increment to next available slot
- add di,cx ; char and attribute
- cmp di,twnd.bend ; would line extend beyond buffer?
- jb putci1 ; b = not beyond end
- mov di,0 ; else start at the beginning
- putci1: mov twnd.pp,di ; update ptr
- cld ; set direction to forward
- push ds ; save regular datas seg reg
- mov ds,tv_segs ; use screen segment for ds:si
- rep movsw ; copy into buffer
- pop ds ; restore regular datas segment
- mov cx,twnd.lmax ; line capacity of buffer
- dec cx ; minus one work space line
- cmp twnd.lcnt,cx ; can we increment line count?
- jae putci1b ; ae = no, keep going
- inc twnd.lcnt ; else count this line
- putci1b:cmp bwnd.lcnt,0 ; any lines in bottom buffer?
- je putci2 ; e = no
- mov cx,bwnd.pp ; see if we overlap bot buf
- cmp cx,twnd.pp ; is this line in bot buf area?
- jne putci2 ; ne = no
- add cl,crt_cols ; move bottom pointer one slot earlier
- adc ch,0
- add cl,crt_cols ; words
- adc ch,0
- cmp cx,bwnd.bend ; beyond end of buffer?
- jb putci1a ; b = no
- mov cx,0 ; yes, start at beginning of buffer
- putci1a:mov bwnd.pp,cx ; new bottom pointer
- dec bwnd.lcnt ; one less line in bottom buffer
- putci2: pop es
- ret
- putci6: ; bottom buffer
- add cx,cx ; words worth
- cmp bwnd.lcnt,0 ; any lines in the buffer yet?
- jne putci7 ; ne = yes
- mov di,twnd.pp ; get latest used slot of top buff
- add di,cx ; where first free (?) slot starts
- cmp di,bwnd.bend ; are we now beyond the buffer?
- jb putci6a ; b = no
- mov di,0 ; yes, start at beginning of buffer
- putci6a:add di,cx ; start of second free (?) slot
- cmp di,bwnd.bend ; are we now beyond the buffer?
- jb putci6b ; b = no
- mov di,0 ; yes, start at beginning of buffer
- putci6b:mov cx,twnd.lmax ; buffer line capacity
- sub cx,twnd.lcnt ; minus number used by top buffer
- sub cx,2 ; minus one work slot and one we need
- cmp cx,0 ; overused some slots?
- jge putci8 ; ge = enough to share
- add twnd.lcnt,cx ; steal these from top window beginning
- jmp short putci8
-
- putci7: mov es,bwnd.orig ; get segment of memory area
- mov di,bwnd.pp ; pick up buffer ptr (offset from es)
- cmp di,0 ; would line start before buffer?
- jne putci7a ; ne = after start of buffer
- mov di,bwnd.bend ; else start at the end minus one slot
- inc di
- putci7a:sub di,cx
- putci8: mov bwnd.pp,di ; update ptr (this is latest used slot)
- mov cl,crt_cols
- xor ch,ch
- cld ; set direction to forward
- push ds ; save regular datas seg reg
- mov ds,tv_segs ; use screen segment for ds:si
- rep movsw ; copy into buffer
- pop ds ; restore regular datas segment
- mov cx,bwnd.lmax ; line capacity of buffer
- cmp bwnd.lcnt,cx ; can we increment line count?
- jae putci8b ; ae = no, keep going
- inc bwnd.lcnt ; else count this line
- putci8b:cmp twnd.lcnt,0 ; any lines in top line buf?
- je putci9 ; e = no
- mov cx,twnd.pp ; yes, see if we used last top line
- cmp cx,bwnd.pp ; where we just wrote
- jne putci9 ; not same place, so all is well
- dec twnd.lcnt ; one less line in top window
- cmp cx,0 ; currently at start of buffer?
- jne putci8a ; ne = no
- mov cx,twnd.bend ; yes
- inc cx
- putci8a:sub cl,crt_cols ; back up top window
- sbb ch,0
- sub cl,crt_cols ; by one line
- sbb ch,0
- mov twnd.pp,cx ; next place to read
- putci9: pop es
- ret
- putcirc endp
-
- ; Get a line from the circular buffer, removing it from the buffer.
- ; returns with carry on if the buffer is empty.
- ; Pass the buffer structure in bx.
- ; Destination preset in es:di which is the current screen address.
- ; Rewritten by [jrd]
- getcirc proc near
- cmp [bx].lcnt,0 ; any lines in buffer?
- jne getci1 ; ne = yes, ok to take one out
- stc ; else set carry
- ret
- getci1: ; top and bottom window common code
- mov cl,crt_cols ; # of chars to copy
- xor ch,ch
- mov si,[bx].pp ; this is source
- push si ; save around calls
- push cx ; save around calls
- cld ; set direction to forward
- push ds ; save original ds
- mov ax,[bx].orig ; use seg address of buffer for si
- mov ds,ax
- rep movsw ; destination = screen at es:di
- pop ds ; recover original data segment
- pop cx ; recover word count
- call scrsync ; synch Topview
- pop si ; get ptr again
- add cx,cx ; words
- cmp bx,offset bwnd ; bottom window?
- je getci7 ; e = yes
- sub si,cx ; top window, move back
- jnc getci6 ; nc = still in buffer, continue
- mov si,twnd.bend ; else use end of buffer
- sub si,cx ; minus length of a piece
- inc si
- getci6: mov twnd.pp,si ; update ptr
- dec twnd.lcnt ; decrement # of lines in buffer
- clc ; make sure no carry
- ret
- getci7: ; bottom window
- add si,cx ; words, move back (bot buf = reverse)
- cmp si,bwnd.bend ; still in buffer?
- jb getci8 ; b = yes
- mov si,0 ; else use beginning of buffer
- getci8: mov bwnd.pp,si ; update ptr
- dec bwnd.lcnt ; decrement # of lines in buffer
- clc ; make sure no carry
- ret
- getcirc endp
-
- ;
- ; CHKDSP - procedure to check for hardware support of 132 cols [dlk]
- ;
- ; Supported hardware: EVA board from Tseng Labs w/132-col kit installed
- ; Tseng Labs UltraPAK mono/Herc board w/132 column modes.
- ; Video 7 Vega Deluxe w/ 132X25.COM driver installed [tmk]
- ; and VGA board, ATI EGA Wonder, Everex ev-659 and fvga-673.
- ; The routine checks for the presence of a 132-column-capable adapter. If
- ; one is found, its handler returns the proper video mode in [CX]. The main-
- ; line code then moves this to [AX] and issues the video interrupt.
- ;
- chgdsp proc near
- push es ; save all we use
- push ax
- push bx
- push cx
- push dx
- push si
- push di
- mov temp,ax ; save set/reset flag from msz
- mov ah,flowoff ; get xoff
- cmp ah,0 ; flow control?
- je chgds0 ; e = none
- call outchr ; send it
- nop ; avoid serial port interrupts while
- nop ; doing many rep scasb's below
- nop
- call savescr ; save current screen
- mov ax,40 ; wait 40 millisec before video tests
- call pcwait ; so don't mix screen and port intrpts
-
- chgds0: call ckteva ; try Tseng Labs EVA
- jnc chgds1 ; nc = found
- call ckv7vd ; try Video 7 EGA Deluxe and VGA
- jnc chgds1 ; nc = found
- call ckatiw ; try ATI EGA Wonder
- jnc chgds1 ; nc = found
- call ckevrx ; try Everex Micro Enhancer Deluxe
- jnc chgds1 ; nc = found
- call ckevga ; try Everex EVGA-673
- jnc chgds1 ; nc = found
- jmp chgdsx ; if not, exit
- ; Perform mode change
- chgds1: mov ax,cx ; get returned value in proper reg
- int screen ; call the bios
- cmp flags.modflg,1 ; is mode line enabled?
- jbe chgds2 ; be = yes, and off or locally owned
- mov flags.modflg,1 ; remove foreign ownership
- chgds2: call scrini ; reset parameters
- chgdsx: mov ah,flowon ; get flowon byte
- cmp ah,0 ; using flow control?
- je chgdsx1 ; e = no
- call outchr ; send it
- nop
- nop
- nop
- chgdsx1:pop di ; restore what we saved
- pop si
- pop dx
- pop cx
- pop bx
- pop ax
- pop es
- ret ; return to caller
- chgdsp endp
-
- ; Individual tests for various 132-column boards
- ;
- ; Tseng LABS EVA and UltraPAK
- ckteva: mov ax,0c000h ; seg addr for EVA
- mov es,ax ; set into es register
- mov di,76h ; offset of board's string
- lea si,tsngid ; validation string
- mov cx,tsnglen ; length of validiation string
- cld
- repe cmpsb ; compare strings
- je ckteva2 ; e = strings match
- mov ax,4d00h ; check for UltraPAK mono driver
- int screen
- cmp ax,5aa5h ; driver signature?
- jne chnoad ; ne = no
- mov cx,7 ; default to mono (7) for this board
- cmp byte ptr temp,0 ; setting 132 columns?
- je ckteva1 ; e = resetting to normal
- mov cx,18h ; set to 132 cols (Set Mode 18H)
- ckteva1:clc ; carry clear means found
- ret
-
- ckteva2: ; an EVA board - check for 132 col kit
- cmp byte ptr es:099h,0 ; check 132 col kit installed
- je chnoad ; e=0=not installed
- jmp catfnd ; do the mode change
-
- chnoad: stc ; indicate adapter not present
- ret ; and exit
- ;
- ; ATI EGA Wonder
- ckatiw: mov ax,0c000h ; seg addr for EGA Wonder
- mov es,ax ; set into es register
- mov di,012fh ; offset of message in ROM
- lea si,atiwid ; offset of message here
- mov cx,atilen ; length of validation string
- cld
- repe cmpsb ; compare strings
- jne chnoad ; ne = strings differ
- ;
- catfnd: mov cx,0003h ; prepare to reset video mode
- cmp byte ptr temp,0 ; are we setting or resetting?
- je ckexit ; e is reset, exit
- mov cx,0023h ; set to 132 cols (Set Mode 23H)
- ckexit: clc ; carry clear means found
- ret
- ;
- ; Video 7 Vega Deluxe
- ckv7vd: mov ax,0c000h ; seg addr for Vega rom bios
- mov es,ax ; set into es register
- mov di,002ah ; offset of message in ROM
- lea si,vid7id ; offset of message here
- mov cx,vid7len
- cld
- repe cmpsb ; compare strings
- je cnv7fn0 ; e = same
- mov di,002ah ; offset of ident string
- mov si,offset vid7id2 ; Video 7 VGA board
- mov cx,vid7len2
- repe cmpsb
- je cnv7fn2 ; e = found
- cnv7fx: jmp chnoad ; ne = strings are different
- ;
- cnv7fn0:test byte ptr es:[03ffeh],1 ; is this a 'Deluxe' Vega?
- jz chnoad ; z = nope, can't do it
- mov ah,35h ; DOS Get Vector
- mov al,10h ; Bios video interrupt
- int dos ; get it into es:bx
- mov di,bx ; es:bx is returned int 10h entry pnt
- sub di,5ah ; back offset to msg in 132X25.COM
- lea si,vid7id ; offset of validation message
- mov cx,vid7len ; length of validation string
- cld
- cnv7fn1:repe cmpsb ; Look for repeat of msg by 132X25.COM
- jne cnv7fn2 ; if different
- mov cl,crt_mode ; prepare to reset video mode
- mov ch,0
- cmp byte ptr temp,0 ; are we setting or resetting?
- je ckexit ; e is reset, exit
- mov cx,0000h ; set to 132 cols (old 40x25)
- jmp short ckexit ; and exit
-
- cnv7fn2:mov ax,6f00h ; check for VegaBios driver
- int screen
- cmp bx,'V7' ; Video 7 Bios presence response
- jne cnv7fx ; ne = not there
- mov ax,6f01h ; al gets monitor type (mono,color,ega)
- int screen
- mov bx,51h ; presume mono 132x25, page 0
- cmp crt_lins,42 ; 43 lines active?
- jb cnv7fn2a ; b = no
- inc bx ; use bx = 52h for 132x43
- cnv7fn2a:
- cmp al,10h ; analogue fixed freq (IBM 85xx)?
- je cnv7fx ; e = yes, no 132 columns
- cmp al,2 ; 1 = mono, 2 = color, above = ega
- jb cnv7fn3 ; b = mono or unknown
- mov bx,4fh ; presume med res color 132x25
- je cnv7fn3 ; e = med res color, al = 2
- mov bx,41h ; ega high res 132x25, enhanced mons
- cmp crt_lins,42 ; 43 lines active?
- jb cnv7fn3 ; b = no
- inc bx ; use bx = 42h for 132x43
- cnv7fn3:mov ax,6f05h ; set special mode found in bl
- cmp byte ptr temp,0 ; resetting to 80 column mode?
- jne cnv7fn4 ; ne = no, setting 132x25
- mov al,crt_norm ; get normal mode
- mov ah,0 ; set mode
- cmp crt_lins,42 ; 43 lines active?
- jb cnv7fn4 ; b = no
- mov bl,40h ; use Video 7 mode 40h 80x43 for color
- mov ax,6f05h ; and do special mode set
- cnv7fn4:int screen ; special mode is in bl
- mov cx,0f00h ; a nop screen bios command
- clc
- ret
-
- ckevrx: mov ax,0c000h ; seg addr for Everex EV-659
- mov es,ax ; set into es register
- mov di,0047h ; offset of message in ROM
- lea si,evrxid ; offset of message here
- mov cx,evrxlen ; length of validation string
- cld
- repe cmpsb ; compare strings
- jne ckfnr2 ; ne = strings differ
- mov ah,crt_lins ; we recognize either 44 or 25 rows
- cmp ah,43 ; equal to 44-1 rows?
- jne ckfnr1 ; ne = no
- mov cx,0070h ; Everex extended mode ident
- mov bl,09h ; prepare to reset video mode to 80x44
- cmp byte ptr temp,0 ; are we setting or resetting?
- je ckfnr4 ; e is reset, exit
- mov bl,0bh ; 132x44
- jmp ckexit
- ckfnr1: cmp ah,24 ; equal to 25-1 rows?
- je ckfnr3 ; e = yes
- ckfnr2: jmp chnoad ; ne = no
- ckfnr3: mov cx,0003h ; prepare to reset video mode
- cmp byte ptr temp,0 ; are we setting or resetting?
- je ckfnr4 ; e is reset, exit
- mov cx,0070h ; Everex extended mode ident
- mov bl,0ah ; 132x25
- ckfnr4: jmp ckexit
- ckevga: mov ax,0c000h ; Everex FVGA-673, rom segment
- mov es,ax
- mov di,76h ; offset in rom for board's id string
- lea si,evgid ; id string
- mov cx,evglen ; length of id string
- cld
- repe cmpsb ; do they match?
- jne ckevg2 ; ne = no
- mov cx,3 ; prepare to reset video mode
- cmp byte ptr temp,0 ; setting or resetting mode?
- je ckevg1 ; e = resetting, exit
- mov cx,0070h ; mode for 132x25
- mov bl,0ah ; Everex mode 0ah
- ckevg1: clc
- ret
- ckevg2: stc ; say board not found
- ret
- ; Jumping to this location is like retskp. It assumes the instruction
- ; after the call is a jmp addr.
-
- RSKP PROC NEAR
- pop bp
- add bp,3
- push bp
- ret
- RSKP ENDP
-
- ; Jumping here is the same as a ret
-
- R PROC NEAR
- ret
- R ENDP
-
- code ends
-
- if1
- %out [End of pass 1]
- else
- %out [End of assembly]
- endif
-
- end
-